package com.globalwave.datasync.sqlgen;


import org.apache.commons.lang.StringUtils;

import com.globalwave.common.db.SqlUtils;
import com.globalwave.datasync.SyncColumn;
import com.globalwave.datasync.SyncConfig;
import com.globalwave.datasync.SyncTable;

public class BaseSqlGenerator {

	protected SyncConfig config ;
	public BaseSqlGenerator(SyncConfig config) {
		this.config = config ;
	}

	public static BaseSqlGenerator getGenerator(SyncConfig config) {
		if (SyncConfig.MODE_INCREMENT_INSERT.equals(config.getModeType())) {
			return new IncrementInsertModeSqlGenerator(config) ;
		} else if (SyncConfig.MODE_MOVE.equals(config.getModeType())) {
			return new MoveModeSqlGenerator(config) ;
		} else{
			return new BaseSqlGenerator(config) ;
		}
	}
	
	public void build() {
		buildSourceQuerySQL() ;
		buildSourceUpdateSQL() ;
		buildSourceDeleteSQL() ;
		
		buildDestinationQuerySQL() ;
		buildDestinationInsertSQL() ;		
		buildDestinationUpdateSQL() ;		
		buildDestinationDeleteSQL() ;
	}
	
	public void buildSourceQuerySQL(){

		if (!StringUtils.isEmpty(config.getSourceQuerySQL())) {
			return ;
		}
		StringBuffer sqlBuffer = new StringBuffer() ;
		SyncTable table = config.getSource() ;

		SyncColumn[] keys = table.getKeys();
		
		sqlBuffer.append(getSelectPart(table)) ;
        
        if (keys != null) {
        	sqlBuffer.append(" where ")
        	         .append(getKeysString(keys))
        	         .append(getFilter(table)) ;
        }

        SqlUtils.getUnlockRead(table.getDbType(), sqlBuffer) ;
      

		config.setSourceQuerySQL(sqlBuffer.toString()) ;
	}
	
	public void buildDestinationQuerySQL(){
		StringBuffer sqlBuffer = new StringBuffer() ;
		
		SyncTable table = config.getDestination() ;
		SyncColumn[] keys = table.getKeys();
		
		sqlBuffer.append(getSelectPart(table)) ;

        
        if (keys != null) {
        	sqlBuffer.append(" where ")
        	         .append(getKeysString(keys))
        	         .append(getFilter(table)) ;
        }
        
        SqlUtils.getUnlockRead(table.getDbType(), sqlBuffer) ;
        
		config.setDestinationQuerySQL(sqlBuffer.toString()) ;
	}
	
	public void buildSourceUpdateSQL(){
		StringBuffer result = new StringBuffer() ;
		result.toString() ;
	}
	
	public void buildSourceDeleteSQL(){
		// do nothing
	}
	
	public void buildDestinationInsertSQL(){
		StringBuffer sqlBuffer = new StringBuffer() ;

		SyncTable table = config.getDestination() ;

		sqlBuffer.append("insert into ").append(table.getTableName()).append("(");
        
		SyncColumn[] columns = table.getSyncColumns();
        for (int i = 0 ; i < columns.length ; i ++) {
            if (i != 0) {
            	sqlBuffer.append(", ") ;
            }
            
            sqlBuffer.append(columns[i].getSyncColumnsCode()) ;
        }
        
		SyncColumn[] keys = table.getKeys();
        for (int i = 0 ; i < keys.length ; i ++) {            
        	sqlBuffer.append(", ").append(keys[i].getSyncColumnsCode()) ;
        }
        
        sqlBuffer.append(" ) values( ") ;
        
        for (int i = 0 ; i < columns.length ; i ++) {
            if (i != 0) {
            	sqlBuffer.append(", ") ;
            }
            sqlBuffer.append("?") ;
        }
        
        for (int i = 0 ; i < keys.length ; i ++) {
        	sqlBuffer.append(", ?") ;
        }
        
        sqlBuffer.append(" ) ") ;
		
		config.setDestinationInsertSQL(sqlBuffer.toString()) ;
	}
	
	public void buildDestinationUpdateSQL(){
		StringBuffer sqlBuffer = new StringBuffer() ;
		
		SyncTable table = config.getDestination() ;
		SyncColumn[] columns = table.getSyncColumns();
		SyncColumn[] keys = table.getKeys();

		sqlBuffer.append(" update ").append(table.getTableName()).append(" set ") ;
        
        for (int i = 0 ; i < columns.length ; i ++) {
            if (i != 0) {
            	sqlBuffer.append(", ") ;
            }
            
            sqlBuffer.append(columns[i].getSyncColumnsCode() + "=? ");
        }
        sqlBuffer.append(" where " + getKeysString(keys)) ;
        
        config.setDestinationUpdateSQL(sqlBuffer.toString());
        
	}
	
	public void buildDestinationDeleteSQL(){
		StringBuffer sqlBuffer = new StringBuffer() ;

		SyncTable table = config.getDestination() ;
		SyncColumn[] keys = table.getKeys();

		sqlBuffer.append("delete from ").append(table.getTableName()) ;
            
		sqlBuffer.append(" where ").append(getKeysString(keys)) ;
        
        config.setDestinationDeleteSQL(sqlBuffer.toString()) ;
	}
	

	
	
	
	protected String getFilter(final SyncTable table) {
        String filter = "" ;
        if (table.getFilter() != null) {
        	for (SyncColumn col : table.getFilter()) {
        	     filter += " and " + col.getSyncColumnsCode() + "=" + col.getDefaultValue() ;
        	}
        }
        
        return filter ;
	}
	
	protected String getSelectPart(final SyncTable table) {
        String sourceQuerySQL = "select " ;

		SyncColumn[] columns = table.getSyncColumns();
		
        for (int i = 0 ; i < columns.length ; i ++) {
            if (i != 0) {
                sourceQuerySQL += ", " ;
            }
            
            sourceQuerySQL += columns[i].getSyncColumnsCode() ;
        }


		SyncColumn[] keys = table.getKeys();
		
        for (int i = 0 ; i < keys.length ; i ++) {
            
            sourceQuerySQL += ", " + keys[i].getSyncColumnsCode() ;
        }
        
        sourceQuerySQL +=" from " + table.getTableName() ;
                
        return sourceQuerySQL ;
        
	}

	
	protected String getKeysString(final SyncColumn[] keys) {

	    String result = " 1=1 " ;
	    
	    for (int i = 0 ; i < keys.length ; i ++) {
	        result += " and " + keys[i].getSyncColumnsCode() + "=? " ;
	    }
	    
	    return result;
			
	}
	
}
